/**
* This file is part of mobileworks.
*
* mobileworks is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* You should have received a copy of the GNU General Public License
* along with dev.clipall.  If not, see <http://www.gnu.org/licenses/>.
*
* https://code.google.com/p/mobileworks/
*/

package gml;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 *
 * @author Erol Hira
 */
public class Packer {
    
    private Fsm fsm;
    
    public Packer(Fsm fsm){
        this.fsm = fsm;
    }
    
    public void pack() throws Exception{
        
        FileOutputStream fos = new FileOutputStream("pack.dat");
                
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(baos);
        
        // propArr
        byte[] arr = bytes(fsm.getPropArr());
        System.out.println("propArr.length : " + arr.length);
        out.writeInt(arr.length);
        out.write(arr, 0, arr.length);
        
        // commandArr
        arr = bytes(fsm.getCommandArr());
        System.out.println("commandArr.length : " + arr.length);
        out.writeInt(arr.length);
        out.write(arr, 0, arr.length);
        
        // transArr
        arr = bytes(fsm.getTransArr());
        System.out.println("transArr.length : " + arr.length);
        out.writeInt(arr.length);
        out.write(arr, 0, arr.length);
        
        // actionArr
        arr = bytes(fsm.getActionArr());
        out.writeInt(arr.length);
        out.write(arr, 0, arr.length);
        
        // funcArr
        arr = bytes(fsm.getFuncArr());
        out.writeInt(arr.length);
        out.write(arr, 0, arr.length);
        
        // styles
        arr = bytes(fsm.getStyles());
        out.writeInt(arr.length);
        out.write(arr, 0, arr.length);
        
        // states
        arr = bytes(fsm.getStates());
        out.writeInt(arr.length);
        out.write(arr, 0, arr.length);
        
        // pages
        arr = bytes(fsm.getPages());
        out.writeInt(arr.length);
        out.write(arr, 0, arr.length);
        
        // nonnumeric prop values
        arr = bytes(fsm.getNonNumericPropValuesArr());
        out.writeInt(arr.length);
        out.write(arr, 0, arr.length);
        
        out.flush();
        out.close();
        
        fos.write(baos.toByteArray());
        fos.flush();
        fos.close();
    }
    
    //---------------------------------------------------------------------
    
    public byte[] bytes(int[][] arr) throws IOException{
        
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(bout);
        
        int l1size = arr.length;
        
        out.writeShort(l1size);
        for(int i = 0; i < l1size; i++){
            
            out.writeShort(arr[i].length);
            
            for(int j = 0; j < arr[i].length; j++){
                
                out.writeShort(arr[i][j]);
            }
        }
        
        out.flush();
        out.close();
        
        return bout.toByteArray();
    }
    
    public byte[] bytes(String[] arr) throws IOException{
        
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(bout);
        
        int size = arr.length;
        
        out.writeShort(size);
        for(int i = 0; i < size; i++){
                        
            out.writeUTF(arr[i]);
        }
        
        out.flush();
        out.close();
        
        return bout.toByteArray();
    }
    
    public byte[] bytes(String[][] arr) throws IOException{
        
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(bout);
        
        int l1size = arr.length;
        
        out.writeShort(l1size);
        for(int i = 0; i < l1size; i++){
            
            out.writeShort(arr[i].length);
            
            for(int j = 0; j < arr[i].length; j++){
                
                out.writeUTF(arr[i][j]);
            }
        }
        
        out.flush();
        out.close();
        
        return bout.toByteArray();
    }
    
    public byte[] bytes(int[][][] arr) throws IOException{
        
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(bout);
        
        int l1size = arr.length;
        
        out.writeShort(l1size);
        for(int i = 0; i < l1size; i++){
            
            out.writeShort(arr[i].length);
            
            for(int j = 0; j < arr[i].length; j++){
                
                out.writeShort(arr[i][j].length);
                
                for(int k = 0; k < arr[i][j].length; k++){
                    
                    out.writeShort(arr[i][j][k]);
                }
            }
        }
        
        out.flush();
        out.close();
        
        return bout.toByteArray();
    }
    
    public byte[] bytes(int[][][][] arr) throws IOException{
        
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(bout);
        
        int l1size = arr.length;
        
        out.writeShort(l1size);
        for(int i = 0; i < l1size; i++){
            
            out.writeShort(arr[i].length);
            
            for(int j = 0; j < arr[i].length; j++){
                
                out.writeShort(arr[i][j].length);
                
                for(int k = 0; k < arr[i][j].length; k++){
                    
                    out.writeShort(arr[i][j][k].length);
                    
                    for(int m = 0; m < arr[i][j][k].length; m++){
                        
                        out.writeShort(arr[i][j][k][m]);
                    }
                }
            }
        }
        
        out.flush();
        out.close();
        
        return bout.toByteArray();
    }
    
}
